using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Web;

namespace PickGold.Charting
{
	[AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
	[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
	public class DataManipulator : DataFormula
	{
		private bool _filterMatchedPoints = true;
		private bool _filterSetEmptyPoints;

		private bool CheckFilterElementCriteria(DateRangeType dateRange, int[] rangeElements, DataPoint point)
		{
			DateTime time = DateTime.FromOADate(point.XValue);
			for (int i = 0; i < rangeElements.Length; i += 2)
			{
				switch (dateRange)
				{
					case DateRangeType.Year:
						if ((time.Year < rangeElements[i]) || (time.Year > rangeElements[i + 1]))
						{
							break;
						}
						return true;

					case DateRangeType.Month:
						if ((time.Month < rangeElements[i]) || (time.Month > rangeElements[i + 1]))
						{
							break;
						}
						return true;

					case DateRangeType.DayOfWeek:
						if (((int)time.DayOfWeek < rangeElements[i]) || ((int)time.DayOfWeek > rangeElements[i + 1]))
						{
							break;
						}
						return true;

					case DateRangeType.DayOfMonth:
						if ((time.Day < rangeElements[i]) || (time.Day > rangeElements[i + 1]))
						{
							break;
						}
						return true;

					case DateRangeType.Hour:
						if ((time.Hour < rangeElements[i]) || (time.Hour > rangeElements[i + 1]))
						{
							break;
						}
						return true;

					case DateRangeType.Minute:
						if ((time.Minute < rangeElements[i]) || (time.Minute > rangeElements[i + 1]))
						{
							break;
						}
						return true;
				}
			}
			return false;
		}

		private void CheckSeriesArrays(Series[] inputSeries, Series[] outputSeries)
		{
			if ((inputSeries == null) || (inputSeries.Length == 0))
			{
				throw new ArgumentException(SR.ExceptionDataManipulatorGroupingInputSeriesUndefined);
			}
			if ((outputSeries != null) && (outputSeries.Length != inputSeries.Length))
			{
				throw new ArgumentException(SR.ExceptionDataManipulatorGroupingInputOutputSeriesNumberMismatch);
			}
		}

		private int[] ConvertElementIndexesToArray(string rangeElements)
		{
			string[] strArray = rangeElements.Split(new char[] { ',' });
			if (strArray.Length == 0)
			{
				throw new ArgumentException(SR.ExceptionDataManipulatorIndexUndefined, "rangeElements");
			}
			int[] numArray = new int[strArray.Length * 2];
			int index = 0;
			foreach (string str in strArray)
			{
				if (str.IndexOf('-') != -1)
				{
					string[] strArray2 = str.Split(new char[] { '-' });
					if (strArray2.Length == 2)
					{
						try
						{
							numArray[index] = int.Parse(strArray2[0], CultureInfo.InvariantCulture);
							numArray[index + 1] = int.Parse(strArray2[1], CultureInfo.InvariantCulture);
							if (numArray[index + 1] < numArray[index])
							{
								int num2 = numArray[index];
								numArray[index] = numArray[index + 1];
								numArray[index + 1] = num2;
							}
							goto Label_0105;
						}
						catch (Exception)
						{
							throw new ArgumentException(SR.ExceptionDataManipulatorIndexFormatInvalid, "rangeElements");
						}
					}
					throw new ArgumentException(SR.ExceptionDataManipulatorIndexFormatInvalid, "rangeElements");
				}
				try
				{
					numArray[index] = int.Parse(str, CultureInfo.InvariantCulture);
					numArray[index + 1] = numArray[index];
				}
				catch (Exception)
				{
					throw new ArgumentException(SR.ExceptionDataManipulatorIndexFormatInvalid, "rangeElements");
				}
			Label_0105:
				index += 2;
			}
			return numArray;
		}

		private DateTimeIntervalType ConvertIntervalType(IntervalType type)
		{
			switch (type)
			{
				case IntervalType.Number:
					return DateTimeIntervalType.Number;

				case IntervalType.Years:
					return DateTimeIntervalType.Years;

				case IntervalType.Months:
					return DateTimeIntervalType.Months;

				case IntervalType.Weeks:
					return DateTimeIntervalType.Weeks;

				case IntervalType.Days:
					return DateTimeIntervalType.Days;

				case IntervalType.Hours:
					return DateTimeIntervalType.Hours;

				case IntervalType.Minutes:
					return DateTimeIntervalType.Minutes;

				case IntervalType.Seconds:
					return DateTimeIntervalType.Seconds;

				case IntervalType.Milliseconds:
					return DateTimeIntervalType.Milliseconds;
			}
			return DateTimeIntervalType.Auto;
		}

		internal Series[] ConvertToSeriesArray(object obj, bool createNew)
		{
			Series[] seriesArray = null;
			if (obj == null)
			{
				return null;
			}
			if (obj.GetType() == typeof(Series))
			{
				return new Series[] { ((Series)obj) };
			}
			if (obj.GetType() == typeof(string))
			{
				string str = (string)obj;
				int index = 0;
				if (str == "*")
				{
					seriesArray = new Series[base.Common.DataManager.Series.Count];
					foreach (Series series in base.Common.DataManager.Series)
					{
						seriesArray[index] = series;
						index++;
					}
					return seriesArray;
				}
				if (str.Length <= 0)
				{
					return seriesArray;
				}
				string[] strArray = str.Replace(@"\,", @"\x45").Replace(@"\=", @"\x46").Split(new char[] { ',' });
				seriesArray = new Series[strArray.Length];
				foreach (string str2 in strArray)
				{
					string str3 = str2.Replace(@"\x45", ",").Replace(@"\x46", "=");
					try
					{
						seriesArray[index] = base.Common.DataManager.Series[str3.Trim()];
					}
					catch (Exception)
					{
						if (!createNew)
						{
							throw;
						}
						Series item = new Series(str3.Trim());
						base.Common.DataManager.Series.Add(item);
						seriesArray[index] = item;
					}
					index++;
				}
			}
			return seriesArray;
		}

		public DataSet ExportSeriesValues()
		{
			return this.ExportSeriesValues("*");
		}

		public DataSet ExportSeriesValues(string seriesNames)
		{
			if (seriesNames == null)
			{
				throw new ArgumentNullException(seriesNames);
			}
			return this.ExportSeriesValues(this.ConvertToSeriesArray(seriesNames, false));
		}

		public DataSet ExportSeriesValues(Series series)
		{
			if (series == null)
			{
				throw new ArgumentNullException("series");
			}
			return this.ExportSeriesValues(this.ConvertToSeriesArray(series, false));
		}

		internal DataSet ExportSeriesValues(Series[] series)
		{
			DataSet set = new DataSet();
			set.Locale = CultureInfo.CurrentCulture;
			if (series != null)
			{
				foreach (Series series2 in series)
				{
					bool flag = true;
					foreach (DataPoint point in series2.Points)
					{
						if (point.XValue != 0.0)
						{
							flag = false;
							break;
						}
					}
					if (flag && (series2.XValueType == ChartValueType.String))
					{
						flag = false;
					}
					DataTable table = new DataTable(series2.Name);
					table.Locale = CultureInfo.CurrentCulture;
					Type type = typeof(double);
					if (series2.IsXValueDateTime())
					{
						type = typeof(DateTime);
					}
					else if (series2.XValueType == ChartValueType.String)
					{
						type = typeof(string);
					}
					table.Columns.Add("X", type);
					type = typeof(double);
					if (series2.IsYValueDateTime())
					{
						type = typeof(DateTime);
					}
					else if (series2.YValueType == ChartValueType.String)
					{
						type = typeof(string);
					}
					for (int i = 0; i < series2.YValuesPerPoint; i++)
					{
						if (i == 0)
						{
							table.Columns.Add("Y", type);
						}
						else
						{
							int num5 = i + 1;
							table.Columns.Add("Y" + num5.ToString(CultureInfo.InvariantCulture), type);
						}
					}
					double num2 = 1.0;
					foreach (DataPoint point2 in series2.Points)
					{
						if (!point2.IsEmpty || !base.IsEmptyPointIgnored)
						{
							DataRow row = table.NewRow();
							object xValue = point2.XValue;
							if (series2.IsXValueDateTime())
							{
								xValue = DateTime.FromOADate(point2.XValue);
							}
							else if (series2.XValueType == ChartValueType.String)
							{
								xValue = point2.AxisLabel;
							}
							row["X"] = flag ? num2 : xValue;
							for (int j = 0; j < series2.YValuesPerPoint; j++)
							{
								object axisLabel = point2.YValues[j];
								if (!point2.IsEmpty)
								{
									if (series2.IsYValueDateTime())
									{
										axisLabel = DateTime.FromOADate(point2.YValues[j]);
									}
									else if (series2.YValueType == ChartValueType.String)
									{
										axisLabel = point2.AxisLabel;
									}
								}
								else if (!base.IsEmptyPointIgnored)
								{
									axisLabel = DBNull.Value;
								}
								if (j == 0)
								{
									row["Y"] = axisLabel;
								}
								else
								{
									int num6 = j + 1;
									row["Y" + num6.ToString(CultureInfo.InvariantCulture)] = axisLabel;
								}
							}
							table.Rows.Add(row);
							num2++;
						}
					}
					table.AcceptChanges();
					set.Tables.Add(table);
				}
			}
			return set;
		}

		public void Filter(IDataPointFilter filterInterface, string inputSeriesNames)
		{
			if (filterInterface == null)
			{
				throw new ArgumentNullException("filterInterface");
			}
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			this.Filter(filterInterface, this.ConvertToSeriesArray(inputSeriesNames, false), null);
		}

		public void Filter(IDataPointFilter filterInterface, Series inputSeries)
		{
			if (filterInterface == null)
			{
				throw new ArgumentNullException("filterInterface");
			}
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Filter(filterInterface, this.ConvertToSeriesArray(inputSeries, false), null);
		}

		public void Filter(CompareMethod compareMethod, double compareValue, string inputSeriesNames)
		{
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			this.Filter(compareMethod, compareValue, inputSeriesNames, "", "Y");
		}

		public void Filter(CompareMethod compareMethod, double compareValue, Series inputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Filter(compareMethod, compareValue, inputSeries, null, "Y");
		}

		public void Filter(DateRangeType dateRange, string rangeElements, string inputSeriesNames)
		{
			if (rangeElements == null)
			{
				throw new ArgumentNullException("rangeElements");
			}
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			this.Filter(dateRange, rangeElements, inputSeriesNames, "");
		}

		public void Filter(DateRangeType dateRange, string rangeElements, Series inputSeries)
		{
			if (rangeElements == null)
			{
				throw new ArgumentNullException("rangeElements");
			}
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Filter(dateRange, rangeElements, inputSeries, (Series)null);
		}

		public void Filter(IDataPointFilter filterInterface, string inputSeriesNames, string outputSeriesNames)
		{
			if (filterInterface == null)
			{
				throw new ArgumentNullException("filterInterface");
			}
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			this.Filter(filterInterface, this.ConvertToSeriesArray(inputSeriesNames, false), this.ConvertToSeriesArray(outputSeriesNames, true));
		}

		private void Filter(IDataPointFilter filterInterface, Series[] inputSeries, Series[] outputSeries)
		{
			this.CheckSeriesArrays(inputSeries, outputSeries);
			base.CheckXValuesAlignment(inputSeries);
			if (filterInterface == null)
			{
				throw new ArgumentNullException("filterInterface");
			}
			Series[] seriesArray = new Series[inputSeries.Length];
			for (int i = 0; i < inputSeries.Length; i++)
			{
				seriesArray[i] = inputSeries[i];
				if ((outputSeries != null) && (outputSeries.Length > i))
				{
					seriesArray[i] = outputSeries[i];
				}
				if (seriesArray[i] != inputSeries[i])
				{
					seriesArray[i].Points.Clear();
					seriesArray[i].YValuesPerPoint = inputSeries[i].YValuesPerPoint;
					if ((seriesArray[i].XValueType == ChartValueType.Auto) || seriesArray[i].autoXValueType)
					{
						seriesArray[i].XValueType = inputSeries[i].XValueType;
						seriesArray[i].autoXValueType = true;
					}
					if ((seriesArray[i].YValueType == ChartValueType.Auto) || seriesArray[i].autoYValueType)
					{
						seriesArray[i].YValueType = inputSeries[i].YValueType;
						seriesArray[i].autoYValueType = true;
					}
				}
			}
			if (inputSeries[0].Points.Count != 0)
			{
				int pointIndex = 0;
				int index = 0;
				while (index < inputSeries[0].Points.Count)
				{
					bool flag = false;
					bool flag2 = filterInterface.FilterDataPoint(inputSeries[0].Points[index], inputSeries[0], pointIndex) == this.FilterMatchedPoints;
					for (int j = 0; j < inputSeries.Length; j++)
					{
						bool flag3 = flag2;
						if (seriesArray[j] != inputSeries[j])
						{
							if (flag3 && !this.FilterSetEmptyPoints)
							{
								flag3 = false;
							}
							else
							{
								seriesArray[j].Points.Add(inputSeries[j].Points[index].Clone());
							}
						}
						if (flag3)
						{
							if (this.FilterSetEmptyPoints)
							{
								seriesArray[j].Points[index].IsEmpty = true;
								for (int k = 0; k < seriesArray[j].Points[index].YValues.Length; k++)
								{
									seriesArray[j].Points[index].YValues[k] = 0.0;
								}
							}
							else
							{
								seriesArray[j].Points.RemoveAt(index);
								flag = true;
							}
						}
					}
					if (flag)
					{
						index--;
					}
					index++;
					pointIndex++;
				}
			}
		}

		public void Filter(IDataPointFilter filterInterface, Series inputSeries, Series outputSeries)
		{
			if (filterInterface == null)
			{
				throw new ArgumentNullException("filterInterface");
			}
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Filter(filterInterface, this.ConvertToSeriesArray(inputSeries, false), this.ConvertToSeriesArray(outputSeries, false));
		}

		public void Filter(CompareMethod compareMethod, double compareValue, string inputSeriesNames, string outputSeriesNames)
		{
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			this.Filter(new PointValueFilter(compareMethod, compareValue, "Y"), this.ConvertToSeriesArray(inputSeriesNames, false), this.ConvertToSeriesArray(outputSeriesNames, true));
		}

		public void Filter(CompareMethod compareMethod, double compareValue, Series inputSeries, Series outputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Filter(new PointValueFilter(compareMethod, compareValue, "Y"), this.ConvertToSeriesArray(inputSeries, false), this.ConvertToSeriesArray(outputSeries, false));
		}

		public void Filter(DateRangeType dateRange, string rangeElements, string inputSeriesNames, string outputSeriesNames)
		{
			if (rangeElements == null)
			{
				throw new ArgumentNullException("rangeElements");
			}
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			this.Filter(new PointElementFilter(this, dateRange, rangeElements), this.ConvertToSeriesArray(inputSeriesNames, false), this.ConvertToSeriesArray(outputSeriesNames, true));
		}

		public void Filter(DateRangeType dateRange, string rangeElements, Series inputSeries, Series outputSeries)
		{
			if (rangeElements == null)
			{
				throw new ArgumentNullException("rangeElements");
			}
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Filter(new PointElementFilter(this, dateRange, rangeElements), this.ConvertToSeriesArray(inputSeries, false), this.ConvertToSeriesArray(outputSeries, false));
		}

		public void Filter(CompareMethod compareMethod, double compareValue, string inputSeriesNames, string outputSeriesNames, string usingValue)
		{
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			if (usingValue == null)
			{
				throw new ArgumentNullException("usingValue");
			}
			this.Filter(new PointValueFilter(compareMethod, compareValue, usingValue), this.ConvertToSeriesArray(inputSeriesNames, false), this.ConvertToSeriesArray(outputSeriesNames, true));
		}

		public void Filter(CompareMethod compareMethod, double compareValue, Series inputSeries, Series outputSeries, string usingValue)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			if (usingValue == null)
			{
				throw new ArgumentNullException("usingValue");
			}
			this.Filter(new PointValueFilter(compareMethod, compareValue, usingValue), this.ConvertToSeriesArray(inputSeries, false), this.ConvertToSeriesArray(outputSeries, false));
		}

		public void FilterTopN(int pointCount, string inputSeriesNames)
		{
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			this.FilterTopN(pointCount, this.ConvertToSeriesArray(inputSeriesNames, false), null, "Y", true);
		}

		public void FilterTopN(int pointCount, Series inputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.FilterTopN(pointCount, this.ConvertToSeriesArray(inputSeries, false), null, "Y", true);
		}

		public void FilterTopN(int pointCount, string inputSeriesNames, string outputSeriesNames)
		{
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			this.FilterTopN(pointCount, this.ConvertToSeriesArray(inputSeriesNames, false), this.ConvertToSeriesArray(outputSeriesNames, true), "Y", true);
		}

		public void FilterTopN(int pointCount, Series inputSeries, Series outputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.FilterTopN(pointCount, this.ConvertToSeriesArray(inputSeries, false), this.ConvertToSeriesArray(outputSeries, false), "Y", true);
		}

		public void FilterTopN(int pointCount, string inputSeriesNames, string outputSeriesNames, string usingValue)
		{
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			if (usingValue == null)
			{
				throw new ArgumentNullException("usingValue");
			}
			this.FilterTopN(pointCount, this.ConvertToSeriesArray(inputSeriesNames, false), this.ConvertToSeriesArray(outputSeriesNames, true), usingValue, true);
		}

		public void FilterTopN(int pointCount, Series inputSeries, Series outputSeries, string usingValue)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			if (usingValue == null)
			{
				throw new ArgumentNullException("usingValue");
			}
			this.FilterTopN(pointCount, this.ConvertToSeriesArray(inputSeries, false), this.ConvertToSeriesArray(outputSeries, false), usingValue, true);
		}

		private void FilterTopN(int pointCount, Series[] inputSeries, Series[] outputSeries, string usingValue, bool getTopValues)
		{
			this.CheckSeriesArrays(inputSeries, outputSeries);
			base.CheckXValuesAlignment(inputSeries);
			if (pointCount <= 0)
			{
				throw new ArgumentOutOfRangeException("pointCount", SR.ExceptionDataManipulatorPointCountIsZero);
			}
			Series[] series = new Series[inputSeries.Length];
			for (int i = 0; i < inputSeries.Length; i++)
			{
				series[i] = inputSeries[i];
				if ((outputSeries != null) && (outputSeries.Length > i))
				{
					series[i] = outputSeries[i];
				}
				if (series[i] != inputSeries[i])
				{
					series[i].Points.Clear();
					series[i].YValuesPerPoint = inputSeries[i].YValuesPerPoint;
					if ((series[i].XValueType == ChartValueType.Auto) || series[i].autoXValueType)
					{
						series[i].XValueType = inputSeries[i].XValueType;
						series[i].autoXValueType = true;
					}
					if ((series[i].YValueType == ChartValueType.Auto) || series[i].autoYValueType)
					{
						series[i].YValueType = inputSeries[i].YValueType;
						series[i].autoYValueType = true;
					}
					foreach (DataPoint point in inputSeries[i].Points)
					{
						series[i].Points.Add(point.Clone());
					}
				}
			}
			if (inputSeries[0].Points.Count != 0)
			{
				this.Sort(getTopValues ? PointSortOrder.Descending : PointSortOrder.Ascending, usingValue, series);
				for (int j = 0; j < inputSeries.Length; j++)
				{
					while (series[j].Points.Count > pointCount)
					{
						if (this.FilterSetEmptyPoints)
						{
							series[j].Points[pointCount].IsEmpty = true;
							pointCount++;
						}
						else
						{
							series[j].Points.RemoveAt(pointCount);
						}
					}
				}
			}
		}

		public void FilterTopN(int pointCount, string inputSeriesNames, string outputSeriesNames, string usingValue, bool getTopValues)
		{
			if (inputSeriesNames == null)
			{
				throw new ArgumentNullException("inputSeriesNames");
			}
			if (usingValue == null)
			{
				throw new ArgumentNullException("usingValue");
			}
			this.FilterTopN(pointCount, this.ConvertToSeriesArray(inputSeriesNames, false), this.ConvertToSeriesArray(outputSeriesNames, true), usingValue, getTopValues);
		}

		public void FilterTopN(int pointCount, Series inputSeries, Series outputSeries, string usingValue, bool getTopValues)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			if (usingValue == null)
			{
				throw new ArgumentNullException("usingValue");
			}
			this.FilterTopN(pointCount, this.ConvertToSeriesArray(inputSeries, false), this.ConvertToSeriesArray(outputSeries, false), usingValue, getTopValues);
		}

		private GroupingFunctionInfo[] GetGroupingFunctions(Series[] inputSeries, string formula, out int outputValuesNumber)
		{
			int num = 0;
			foreach (Series series in inputSeries)
			{
				num = Math.Max(num, series.YValuesPerPoint);
			}
			GroupingFunctionInfo[] infoArray = new GroupingFunctionInfo[num + 1];
			for (int i = 0; i < infoArray.Length; i++)
			{
				infoArray[i] = new GroupingFunctionInfo();
			}
			string[] strArray = formula.Split(new char[] { ',' });
			if (strArray.Length == 0)
			{
				throw new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaUndefined);
			}
			GroupingFunctionInfo info = new GroupingFunctionInfo();
			foreach (string str in strArray)
			{
				string formulaString = str.Trim().ToUpper(CultureInfo.InvariantCulture);
				int valueIndex = 1;
				GroupingFunction function = this.ParseFormulaAndValueType(formulaString, out valueIndex);
				if (info.function == GroupingFunction.None)
				{
					info.function = function;
				}
				if (valueIndex >= infoArray.Length)
				{
					throw new ArgumentException(SR.ExceptionDataManipulatorYValuesIndexExceeded(formulaString));
				}
				if (infoArray[valueIndex].function != GroupingFunction.None)
				{
					throw new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaAlreadyDefined(formulaString));
				}
				infoArray[valueIndex].function = function;
			}
			if (infoArray[0].function == GroupingFunction.None)
			{
				infoArray[0].function = GroupingFunction.First;
			}
			for (int j = 1; j < infoArray.Length; j++)
			{
				if (infoArray[j].function == GroupingFunction.None)
				{
					infoArray[j].function = info.function;
				}
			}
			outputValuesNumber = 0;
			for (int k = 0; k < infoArray.Length; k++)
			{
				infoArray[k].outputIndex = outputValuesNumber;
				if (infoArray[k].function == GroupingFunction.HiLoOpCl)
				{
					outputValuesNumber += 3;
				}
				else if (infoArray[k].function == GroupingFunction.HiLo)
				{
					outputValuesNumber++;
				}
				outputValuesNumber++;
			}
			if (((infoArray[0].function != GroupingFunction.First) && (infoArray[0].function != GroupingFunction.Last)) && (infoArray[0].function != GroupingFunction.Center))
			{
				throw new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaUnsupported);
			}
			return infoArray;
		}

		public void Group(string formula, double interval, IntervalType intervalType, string inputSeriesName)
		{
			if (inputSeriesName == null)
			{
				throw new ArgumentNullException("inputSeriesName");
			}
			this.Group(formula, interval, intervalType, inputSeriesName, "");
		}

		public void Group(string formula, double interval, IntervalType intervalType, Series inputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Group(formula, interval, intervalType, inputSeries, null);
		}

		public void Group(string formula, double interval, IntervalType intervalType, string inputSeriesName, string outputSeriesName)
		{
			if (inputSeriesName == null)
			{
				throw new ArgumentNullException("inputSeriesName");
			}
			this.Group(formula, interval, intervalType, 0.0, IntervalType.Number, inputSeriesName, outputSeriesName);
		}

		public void Group(string formula, double interval, IntervalType intervalType, Series inputSeries, Series outputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Group(formula, interval, intervalType, 0.0, IntervalType.Number, inputSeries, outputSeries);
		}

		public void Group(string formula, double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, string inputSeriesName)
		{
			if (inputSeriesName == null)
			{
				throw new ArgumentNullException("inputSeriesName");
			}
			this.Group(formula, interval, intervalType, intervalOffset, intervalOffsetType, inputSeriesName, "");
		}

		public void Group(string formula, double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, Series inputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Group(formula, interval, intervalType, intervalOffset, intervalOffsetType, inputSeries, null);
		}

		public void Group(string formula, double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, string inputSeriesName, string outputSeriesName)
		{
			if (inputSeriesName == null)
			{
				throw new ArgumentNullException("inputSeriesName");
			}
			this.Group(formula, interval, intervalType, intervalOffset, intervalOffsetType, this.ConvertToSeriesArray(inputSeriesName, false), this.ConvertToSeriesArray(outputSeriesName, true));
		}

		public void Group(string formula, double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, Series inputSeries, Series outputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.Group(formula, interval, intervalType, intervalOffset, intervalOffsetType, this.ConvertToSeriesArray(inputSeries, false), this.ConvertToSeriesArray(outputSeries, false));
		}

		private void Group(string formula, double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, Series[] inputSeries, Series[] outputSeries)
		{
			if (formula == null)
			{
				throw new ArgumentNullException("formula");
			}
			this.CheckSeriesArrays(inputSeries, outputSeries);
			int outputValuesNumber = 1;
			GroupingFunctionInfo[] functions = this.GetGroupingFunctions(inputSeries, formula, out outputValuesNumber);
			for (int i = 0; i < inputSeries.Length; i++)
			{
				Series series = inputSeries[i];
				Series series2 = series;
				if ((outputSeries != null) && (i < outputSeries.Length))
				{
					series2 = outputSeries[i];
					if (series2.Name != series.Name)
					{
						series2.Points.Clear();
						if ((series2.XValueType == ChartValueType.Auto) || series2.autoXValueType)
						{
							series2.XValueType = series.XValueType;
							series2.autoXValueType = true;
						}
						if ((series2.YValueType == ChartValueType.Auto) || series2.autoYValueType)
						{
							series2.YValueType = series.YValueType;
							series2.autoYValueType = true;
						}
					}
				}
				if (series.Points.Count != 0)
				{
					series2.YValuesPerPoint = outputValuesNumber - 1;
					int intervalFirstIndex = 0;
					int intervalLastIndex = 0;
					double current = 0.0;
					double num6 = 0.0;
					current = ChartHelper.AlignIntervalStart(series.Points[0].XValue, interval, this.ConvertIntervalType(intervalType));
					double num7 = 0.0;
					if (intervalOffset != 0.0)
					{
						num7 = current + ChartHelper.GetIntervalSize(current, intervalOffset, this.ConvertIntervalType(intervalOffsetType));
						if (series.Points[0].XValue < num7)
						{
							if (intervalType == IntervalType.Number)
							{
								current = num7 + ChartHelper.GetIntervalSize(num7, -interval, this.ConvertIntervalType(intervalType));
							}
							else
							{
								current = num7 - ChartHelper.GetIntervalSize(num7, interval, this.ConvertIntervalType(intervalType));
							}
							num6 = num7;
						}
						else
						{
							current = num7;
							num6 = current + ChartHelper.GetIntervalSize(current, interval, this.ConvertIntervalType(intervalType));
						}
					}
					else
					{
						num6 = current + ChartHelper.GetIntervalSize(current, interval, this.ConvertIntervalType(intervalType));
					}
					double[] pointTempValues = new double[outputValuesNumber];
					bool flag = false;
					int numberOfEmptyPoints = 0;
					int num9 = 0;
					for (int j = 0; (j <= series.Points.Count) && !flag; j++)
					{
						bool flag2 = false;
						if (((j > 0) && (j < series.Points.Count)) && (series.Points[j].XValue < series.Points[j - 1].XValue))
						{
							throw new InvalidOperationException(SR.ExceptionDataManipulatorGroupedSeriesNotSorted);
						}
						if (j == series.Points.Count)
						{
							flag = true;
							intervalLastIndex = j - 1;
							j = intervalLastIndex;
							flag2 = true;
						}
						if (!flag2 && (series.Points[j].XValue >= num6))
						{
							if (j == 0)
							{
								goto Label_03B8;
							}
							intervalLastIndex = j - 1;
							flag2 = true;
						}
						if (flag2)
						{
							if (num9 > numberOfEmptyPoints)
							{
								this.ProcessPointValues(functions, pointTempValues, inputSeries[i], series.Points[j], j, intervalFirstIndex, intervalLastIndex, true, ref numberOfEmptyPoints);
								if (functions[0].function == GroupingFunction.Center)
								{
									pointTempValues[0] = (current + num6) / 2.0;
								}
								else if (functions[0].function == GroupingFunction.First)
								{
									pointTempValues[0] = current;
								}
								if (functions[0].function == GroupingFunction.Last)
								{
									pointTempValues[0] = num6;
								}
								DataPoint item = new DataPoint();
								item.ResizeYValueArray(outputValuesNumber - 1);
								item.XValue = pointTempValues[0];
								for (int k = 1; k < pointTempValues.Length; k++)
								{
									item.YValues[k - 1] = pointTempValues[k];
								}
								int count = series2.Points.Count;
								if (series2 == series)
								{
									count = intervalFirstIndex;
									j = count + 1;
									for (int m = intervalFirstIndex; m <= intervalLastIndex; m++)
									{
										series2.Points.RemoveAt(intervalFirstIndex);
									}
								}
								series2.Points.Insert(count, item);
							}
							current = num6;
							num6 = current + ChartHelper.GetIntervalSize(current, interval, this.ConvertIntervalType(intervalType));
							intervalFirstIndex = j;
							intervalLastIndex = j;
							num9 = 0;
							numberOfEmptyPoints = 0;
							j--;
						}
						else
						{
							this.ProcessPointValues(functions, pointTempValues, inputSeries[i], series.Points[j], j, intervalFirstIndex, intervalLastIndex, false, ref numberOfEmptyPoints);
							num9++;
						}
					Label_03B8: ;
					}
				}
			}
		}

		public void GroupByAxisLabel(string formula, string inputSeriesName)
		{
			if (inputSeriesName == null)
			{
				throw new ArgumentNullException("inputSeriesName");
			}
			this.GroupByAxisLabel(formula, inputSeriesName, null);
		}

		public void GroupByAxisLabel(string formula, Series inputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.GroupByAxisLabel(formula, inputSeries, null);
		}

		public void GroupByAxisLabel(string formula, string inputSeriesName, string outputSeriesName)
		{
			if (inputSeriesName == null)
			{
				throw new ArgumentNullException("inputSeriesName");
			}
			this.GroupByAxisLabel(formula, this.ConvertToSeriesArray(inputSeriesName, false), this.ConvertToSeriesArray(outputSeriesName, true));
		}

		private void GroupByAxisLabel(string formula, Series[] inputSeries, Series[] outputSeries)
		{
			if (formula == null)
			{
				throw new ArgumentNullException("formula");
			}
			this.CheckSeriesArrays(inputSeries, outputSeries);
			int outputValuesNumber = 1;
			GroupingFunctionInfo[] functions = this.GetGroupingFunctions(inputSeries, formula, out outputValuesNumber);
			for (int i = 0; i < inputSeries.Length; i++)
			{
				Series series = inputSeries[i];
				Series series2 = series;
				if ((outputSeries != null) && (i < outputSeries.Length))
				{
					series2 = outputSeries[i];
					if (series2.Name != series.Name)
					{
						series2.Points.Clear();
						if ((series2.XValueType == ChartValueType.Auto) || series2.autoXValueType)
						{
							series2.XValueType = series.XValueType;
							series2.autoXValueType = true;
						}
						if ((series2.YValueType == ChartValueType.Auto) || series2.autoYValueType)
						{
							series2.YValueType = series.YValueType;
							series2.autoYValueType = true;
						}
					}
				}
				if (series != series2)
				{
					Series series3 = new Series("Temp", series.YValuesPerPoint);
					foreach (DataPoint point in series.Points)
					{
						DataPoint item = new DataPoint(series3);
						item.AxisLabel = point.AxisLabel;
						item.XValue = point.XValue;
						point.YValues.CopyTo(item.YValues, 0);
						item.IsEmpty = point.IsEmpty;
						series3.Points.Add(item);
					}
					series = series3;
				}
				if (series.Points.Count != 0)
				{
					series2.YValuesPerPoint = outputValuesNumber - 1;
					series.Sort(PointSortOrder.Ascending, "AxisLabel");
					int intervalFirstIndex = 0;
					int intervalLastIndex = 0;
					double[] pointTempValues = new double[outputValuesNumber];
					string axisLabel = null;
					bool flag = false;
					int numberOfEmptyPoints = 0;
					for (int j = 0; (j <= series.Points.Count) && !flag; j++)
					{
						bool flag2 = false;
						if (j == series.Points.Count)
						{
							flag = true;
							intervalLastIndex = j - 1;
							j = intervalLastIndex;
							flag2 = true;
						}
						if (!flag2 && (axisLabel == null))
						{
							axisLabel = series.Points[j].AxisLabel;
						}
						if (!flag2 && (series.Points[j].AxisLabel != axisLabel))
						{
							intervalLastIndex = j - 1;
							flag2 = true;
						}
						if (flag2)
						{
							this.ProcessPointValues(functions, pointTempValues, inputSeries[i], series.Points[j], j, intervalFirstIndex, intervalLastIndex, true, ref numberOfEmptyPoints);
							if (functions[0].function == GroupingFunction.Center)
							{
								pointTempValues[0] = (inputSeries[i].Points[intervalFirstIndex].XValue + inputSeries[i].Points[intervalLastIndex].XValue) / 2.0;
							}
							else if (functions[0].function == GroupingFunction.First)
							{
								pointTempValues[0] = inputSeries[i].Points[intervalFirstIndex].XValue;
							}
							if (functions[0].function == GroupingFunction.Last)
							{
								pointTempValues[0] = inputSeries[i].Points[intervalLastIndex].XValue;
							}
							DataPoint point3 = new DataPoint();
							point3.ResizeYValueArray(outputValuesNumber - 1);
							point3.XValue = pointTempValues[0];
							point3.AxisLabel = axisLabel;
							for (int k = 1; k < pointTempValues.Length; k++)
							{
								point3.YValues[k - 1] = pointTempValues[k];
							}
							int count = series2.Points.Count;
							if (series2 == series)
							{
								count = intervalFirstIndex;
								j = count + 1;
								for (int m = intervalFirstIndex; m <= intervalLastIndex; m++)
								{
									series2.Points.RemoveAt(intervalFirstIndex);
								}
							}
							series2.Points.Insert(count, point3);
							intervalFirstIndex = j;
							intervalLastIndex = j;
							numberOfEmptyPoints = 0;
							axisLabel = null;
							j--;
						}
						else
						{
							this.ProcessPointValues(functions, pointTempValues, inputSeries[i], series.Points[j], j, intervalFirstIndex, intervalLastIndex, false, ref numberOfEmptyPoints);
						}
					}
				}
			}
		}

		public void GroupByAxisLabel(string formula, Series inputSeries, Series outputSeries)
		{
			if (inputSeries == null)
			{
				throw new ArgumentNullException("inputSeries");
			}
			this.GroupByAxisLabel(formula, this.ConvertToSeriesArray(inputSeries, false), this.ConvertToSeriesArray(outputSeries, false));
		}

		public void InsertEmptyPoints(double interval, IntervalType intervalType, string seriesName)
		{
			this.InsertEmptyPoints(interval, intervalType, 0.0, IntervalType.Number, seriesName);
		}

		public void InsertEmptyPoints(double interval, IntervalType intervalType, Series series)
		{
			this.InsertEmptyPoints(interval, intervalType, 0.0, IntervalType.Number, series);
		}

		public void InsertEmptyPoints(double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, string seriesName)
		{
			this.InsertEmptyPoints(interval, intervalType, intervalOffset, intervalOffsetType, double.NaN, double.NaN, seriesName);
		}

		public void InsertEmptyPoints(double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, Series series)
		{
			this.InsertEmptyPoints(interval, intervalType, intervalOffset, intervalOffsetType, double.NaN, double.NaN, series);
		}

		private void InsertEmptyPoints(double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, double fromXValue, double toXValue, Series[] series)
		{
			if (interval <= 0.0)
			{
				throw new ArgumentOutOfRangeException("interval");
			}
			double d = Math.Min(fromXValue, toXValue);
			double xValue = Math.Max(fromXValue, toXValue);
			bool flag = double.IsNaN(d);
			bool flag2 = double.IsNaN(xValue);
			foreach (Series series2 in series)
			{
				if (series2.Points.Count >= 1)
				{
					if (flag2)
					{
						if (double.IsNaN(xValue))
						{
							xValue = series2.Points[series2.Points.Count - 1].XValue;
						}
						else
						{
							xValue = Math.Max(xValue, series2.Points[series2.Points.Count - 1].XValue);
						}
					}
					if (flag)
					{
						if (double.IsNaN(d))
						{
							d = series2.Points[0].XValue;
						}
						else
						{
							d = Math.Min(d, series2.Points[0].XValue);
						}
					}
					if (d > xValue)
					{
						double num3 = d;
						d = xValue;
						xValue = num3;
					}
				}
			}
			double num4 = d;
			d = ChartHelper.AlignIntervalStart(d, interval, this.ConvertIntervalType(intervalType));
			if (intervalOffset != 0.0)
			{
				d += ChartHelper.GetIntervalSize(d, intervalOffset, this.ConvertIntervalType(intervalOffsetType), null, 0.0, DateTimeIntervalType.Number, true, false);
			}
			foreach (Series series3 in series)
			{
				int num5 = 0;
				int num6 = 0;
				double current = d;
				while (current <= xValue)
				{
					bool flag3 = false;
					if ((double.IsNaN(fromXValue) && (current < num4)) || (!double.IsNaN(fromXValue) && (current < fromXValue)))
					{
						flag3 = true;
					}
					else if (current > toXValue)
					{
						flag3 = true;
					}
					if (!flag3)
					{
						int index = num6;
						for (int i = num6; i < series3.Points.Count; i++)
						{
							if (series3.Points[i].XValue == current)
							{
								index = -1;
								break;
							}
							if (series3.Points[i].XValue > current)
							{
								index = i;
								break;
							}
							if (i == (series3.Points.Count - 1))
							{
								index = series3.Points.Count;
							}
						}
						if (index != -1)
						{
							num6 = index;
							num5++;
							DataPoint item = new DataPoint(series3);
							item.XValue = current;
							item.IsEmpty = true;
							series3.Points.Insert(index, item);
						}
					}
					current += ChartHelper.GetIntervalSize(current, interval, this.ConvertIntervalType(intervalType));
					if (num5 > 0x3e8)
					{
						current = xValue + 1.0;
					}
				}
			}
		}

		public void InsertEmptyPoints(double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, double fromXValue, double toXValue, string seriesName)
		{
			if (seriesName == null)
			{
				throw new ArgumentNullException("seriesName");
			}
			this.InsertEmptyPoints(interval, intervalType, intervalOffset, intervalOffsetType, fromXValue, toXValue, this.ConvertToSeriesArray(seriesName, false));
		}

		public void InsertEmptyPoints(double interval, IntervalType intervalType, double intervalOffset, IntervalType intervalOffsetType, double fromXValue, double toXValue, Series series)
		{
			if (series == null)
			{
				throw new ArgumentNullException("series");
			}
			this.InsertEmptyPoints(interval, intervalType, intervalOffset, intervalOffsetType, fromXValue, toXValue, this.ConvertToSeriesArray(series, false));
		}

		private GroupingFunction ParseFormulaAndValueType(string formulaString, out int valueIndex)
		{
			valueIndex = 1;
			string[] strArray = formulaString.Split(new char[] { ':' });
			if ((strArray.Length < 1) && (strArray.Length > 2))
			{
				throw new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaFormatInvalid(formulaString));
			}
			if (strArray.Length == 2)
			{
				if (strArray[0] != "X")
				{
					if (strArray[0].StartsWith("Y", StringComparison.Ordinal))
					{
						strArray[0] = strArray[0].TrimStart(new char[] { 'Y' });
						if (strArray[0].Length == 0)
						{
							valueIndex = 1;
							goto Label_00AA;
						}
						try
						{
							valueIndex = int.Parse(strArray[0], CultureInfo.InvariantCulture);
							goto Label_00AA;
						}
						catch (Exception)
						{
							throw new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaFormatInvalid(formulaString));
						}
					}
					throw new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaFormatInvalid(formulaString));
				}
				valueIndex = 0;
			}
		Label_00AA:
			if (strArray[strArray.Length - 1] == "MIN")
			{
				return GroupingFunction.Min;
			}
			if (strArray[strArray.Length - 1] == "MAX")
			{
				return GroupingFunction.Max;
			}
			if (strArray[strArray.Length - 1] == "AVE")
			{
				return GroupingFunction.Ave;
			}
			if (strArray[strArray.Length - 1] == "SUM")
			{
				return GroupingFunction.Sum;
			}
			if (strArray[strArray.Length - 1] == "FIRST")
			{
				return GroupingFunction.First;
			}
			if (strArray[strArray.Length - 1] == "LAST")
			{
				return GroupingFunction.Last;
			}
			if (strArray[strArray.Length - 1] == "HILOOPCL")
			{
				return GroupingFunction.HiLoOpCl;
			}
			if (strArray[strArray.Length - 1] == "HILO")
			{
				return GroupingFunction.HiLo;
			}
			if (strArray[strArray.Length - 1] == "COUNT")
			{
				return GroupingFunction.Count;
			}
			if (strArray[strArray.Length - 1] == "DISTINCTCOUNT")
			{
				return GroupingFunction.DistinctCount;
			}
			if (strArray[strArray.Length - 1] == "VARIANCE")
			{
				return GroupingFunction.Variance;
			}
			if (strArray[strArray.Length - 1] == "DEVIATION")
			{
				return GroupingFunction.Deviation;
			}
			if (strArray[strArray.Length - 1] != "CENTER")
			{
				throw new ArgumentException(SR.ExceptionDataManipulatorGroupingFormulaNameInvalid(formulaString));
			}
			return GroupingFunction.Center;
		}

		private void ProcessPointValues(GroupingFunctionInfo[] functions, double[] pointTempValues, Series series, DataPoint point, int pointIndex, int intervalFirstIndex, int intervalLastIndex, bool finalPass, ref int numberOfEmptyPoints)
		{
			if ((pointIndex == intervalFirstIndex) && !finalPass)
			{
				int num = 0;
				foreach (GroupingFunctionInfo info in functions)
				{
					if (num > point.YValues.Length)
					{
						break;
					}
					pointTempValues[info.outputIndex] = 0.0;
					if (info.function == GroupingFunction.Min)
					{
						pointTempValues[info.outputIndex] = double.MaxValue;
					}
					else if (info.function == GroupingFunction.Max)
					{
						pointTempValues[info.outputIndex] = double.MinValue;
					}
					else if (info.function == GroupingFunction.First)
					{
						if (num == 0)
						{
							pointTempValues[0] = point.XValue;
						}
						else
						{
							pointTempValues[info.outputIndex] = point.YValues[num - 1];
						}
					}
					else if ((info.function == GroupingFunction.HiLo) || (info.function == GroupingFunction.HiLoOpCl))
					{
						pointTempValues[info.outputIndex] = double.MinValue;
						pointTempValues[info.outputIndex + 1] = double.MaxValue;
						if (info.function == GroupingFunction.HiLoOpCl)
						{
							pointTempValues[info.outputIndex + 2] = point.YValues[num - 1];
							pointTempValues[info.outputIndex + 3] = 0.0;
						}
					}
					num++;
				}
			}
			if (!finalPass)
			{
				if (point.IsEmpty && base.IsEmptyPointIgnored)
				{
					numberOfEmptyPoints++;
					return;
				}
				int num2 = 0;
				foreach (GroupingFunctionInfo info2 in functions)
				{
					if (num2 > point.YValues.Length)
					{
						break;
					}
					if (((info2.function == GroupingFunction.Min) && !point.IsEmpty) && base.IsEmptyPointIgnored)
					{
						pointTempValues[info2.outputIndex] = Math.Min(pointTempValues[info2.outputIndex], point.YValues[num2 - 1]);
					}
					else if (info2.function == GroupingFunction.Max)
					{
						pointTempValues[info2.outputIndex] = Math.Max(pointTempValues[info2.outputIndex], point.YValues[num2 - 1]);
					}
					else if ((info2.function == GroupingFunction.Ave) || (info2.function == GroupingFunction.Sum))
					{
						if (num2 == 0)
						{
							pointTempValues[0] += point.XValue;
						}
						else
						{
							pointTempValues[info2.outputIndex] += point.YValues[num2 - 1];
						}
					}
					else if ((info2.function == GroupingFunction.Variance) || (info2.function == GroupingFunction.Deviation))
					{
						pointTempValues[info2.outputIndex] += point.YValues[num2 - 1];
					}
					else if (info2.function == GroupingFunction.Last)
					{
						if (num2 == 0)
						{
							pointTempValues[0] = point.XValue;
						}
						else
						{
							pointTempValues[info2.outputIndex] = point.YValues[num2 - 1];
						}
					}
					else if (info2.function == GroupingFunction.Count)
					{
						pointTempValues[info2.outputIndex]++;
					}
					else if ((info2.function == GroupingFunction.HiLo) || (info2.function == GroupingFunction.HiLoOpCl))
					{
						pointTempValues[info2.outputIndex] = Math.Max(pointTempValues[info2.outputIndex], point.YValues[num2 - 1]);
						pointTempValues[info2.outputIndex + 1] = Math.Min(pointTempValues[info2.outputIndex + 1], point.YValues[num2 - 1]);
						if (info2.function == GroupingFunction.HiLoOpCl)
						{
							pointTempValues[info2.outputIndex + 3] = point.YValues[num2 - 1];
						}
					}
					num2++;
				}
			}
			if (finalPass)
			{
				int num3 = 0;
				foreach (GroupingFunctionInfo info3 in functions)
				{
					if (num3 > point.YValues.Length)
					{
						return;
					}
					if (info3.function == GroupingFunction.Ave)
					{
						pointTempValues[info3.outputIndex] /= (double)(((intervalLastIndex - intervalFirstIndex) - numberOfEmptyPoints) + 1);
					}
					if (info3.function == GroupingFunction.DistinctCount)
					{
						pointTempValues[info3.outputIndex] = 0.0;
						ArrayList list = new ArrayList((intervalLastIndex - intervalFirstIndex) + 1);
						for (int i = intervalFirstIndex; i <= intervalLastIndex; i++)
						{
							if ((!series.Points[i].IsEmpty || !base.IsEmptyPointIgnored) && !list.Contains(series.Points[i].YValues[num3 - 1]))
							{
								list.Add(series.Points[i].YValues[num3 - 1]);
							}
						}
						pointTempValues[info3.outputIndex] = list.Count;
					}
					else if ((info3.function == GroupingFunction.Variance) || (info3.function == GroupingFunction.Deviation))
					{
						double num5 = pointTempValues[info3.outputIndex] / ((double)(((intervalLastIndex - intervalFirstIndex) - numberOfEmptyPoints) + 1));
						pointTempValues[info3.outputIndex] = 0.0;
						for (int j = intervalFirstIndex; j <= intervalLastIndex; j++)
						{
							if (!series.Points[j].IsEmpty || !base.IsEmptyPointIgnored)
							{
								pointTempValues[info3.outputIndex] += Math.Pow(series.Points[j].YValues[num3 - 1] - num5, 2.0);
							}
						}
						pointTempValues[info3.outputIndex] /= (double)(((intervalLastIndex - intervalFirstIndex) - numberOfEmptyPoints) + 1);
						if (info3.function == GroupingFunction.Deviation)
						{
							pointTempValues[info3.outputIndex] = Math.Sqrt(pointTempValues[info3.outputIndex]);
						}
					}
					num3++;
				}
			}
		}

		public void Sort(IComparer<DataPoint> comparer, string seriesName)
		{
			if (seriesName == null)
			{
				throw new ArgumentNullException("seriesName");
			}
			this.Sort(comparer, this.ConvertToSeriesArray(seriesName, false));
		}

		public void Sort(IComparer<DataPoint> comparer, Series series)
		{
			if (series == null)
			{
				throw new ArgumentNullException("series");
			}
			this.Sort(comparer, this.ConvertToSeriesArray(series, false));
		}

		private void Sort(IComparer<DataPoint> comparer, Series[] series)
		{
			if (comparer == null)
			{
				throw new ArgumentNullException("comparer");
			}
			if (series == null)
			{
				throw new ArgumentNullException("series");
			}
			if (series.Length != 0)
			{
				if (series.Length > 1)
				{
					base.CheckXValuesAlignment(series);
					int num = 0;
					foreach (DataPoint point in series[0].Points)
					{
						point["_Index"] = num.ToString(CultureInfo.InvariantCulture);
						num++;
					}
				}
				series[0].Sort(comparer);
				if (series.Length > 1)
				{
					int index = 0;
					int num3 = 0;
					foreach (DataPoint point2 in series[0].Points)
					{
						num3 = int.Parse(point2["_Index"], CultureInfo.InvariantCulture);
						for (int j = 1; j < series.Length; j++)
						{
							series[j].Points.Insert(index, series[j].Points[index + num3]);
						}
						index++;
					}
					for (int i = 1; i < series.Length; i++)
					{
						while (series[i].Points.Count > series[0].Points.Count)
						{
							series[i].Points.RemoveAt(series[i].Points.Count - 1);
						}
					}
					foreach (DataPoint point3 in series[0].Points)
					{
						point3.DeleteCustomProperty("_Index");
					}
				}
			}
		}

		public void Sort(PointSortOrder pointSortOrder, string seriesName)
		{
			if (seriesName == null)
			{
				throw new ArgumentNullException("seriesName");
			}
			this.Sort(pointSortOrder, "Y", this.ConvertToSeriesArray(seriesName, false));
		}

		public void Sort(PointSortOrder pointSortOrder, Series series)
		{
			if (series == null)
			{
				throw new ArgumentNullException("series");
			}
			this.Sort(pointSortOrder, "Y", this.ConvertToSeriesArray(series, false));
		}

		private void Sort(PointSortOrder pointSortOrder, string sortBy, Series[] series)
		{
			if (sortBy == null)
			{
				throw new ArgumentNullException("sortBy");
			}
			if (series == null)
			{
				throw new ArgumentNullException("series");
			}
			if (series.Length != 0)
			{
				DataPointComparer comparer = new DataPointComparer(series[0], pointSortOrder, sortBy);
				this.Sort(comparer, series);
			}
		}

		public void Sort(PointSortOrder pointSortOrder, string sortBy, string seriesName)
		{
			if (seriesName == null)
			{
				throw new ArgumentNullException("seriesName");
			}
			this.Sort(pointSortOrder, sortBy, this.ConvertToSeriesArray(seriesName, false));
		}

		public void Sort(PointSortOrder pointSortOrder, string sortBy, Series series)
		{
			if (series == null)
			{
				throw new ArgumentNullException("series");
			}
			this.Sort(pointSortOrder, sortBy, this.ConvertToSeriesArray(series, false));
		}

		public bool FilterMatchedPoints
		{
			get
			{
				return this._filterMatchedPoints;
			}
			set
			{
				this._filterMatchedPoints = value;
			}
		}

		public bool FilterSetEmptyPoints
		{
			get
			{
				return this._filterSetEmptyPoints;
			}
			set
			{
				this._filterSetEmptyPoints = value;
			}
		}

		private class GroupingFunctionInfo
		{
			internal GroupingFunction function;
			internal int outputIndex;

			internal GroupingFunctionInfo()
			{
			}
		}

		private class PointElementFilter : IDataPointFilter
		{
			private DataManipulator _dataManipulator;
			private DateRangeType _dateRange;
			private int[] _rangeElements;

			private PointElementFilter()
			{
			}

			public PointElementFilter(DataManipulator dataManipulator, DateRangeType dateRange, string rangeElements)
			{
				this._dataManipulator = dataManipulator;
				this._dateRange = dateRange;
				this._rangeElements = dataManipulator.ConvertElementIndexesToArray(rangeElements);
			}

			public bool FilterDataPoint(DataPoint point, Series series, int pointIndex)
			{
				return this._dataManipulator.CheckFilterElementCriteria(this._dateRange, this._rangeElements, point);
			}
		}

		private class PointValueFilter : IDataPointFilter
		{
			private CompareMethod _compareMethod;
			private double _compareValue;
			private string _usingValue;

			private PointValueFilter()
			{
			}

			public PointValueFilter(CompareMethod compareMethod, double compareValue, string usingValue)
			{
				this._compareMethod = compareMethod;
				this._usingValue = usingValue;
				this._compareValue = compareValue;
			}

			public bool FilterDataPoint(DataPoint point, Series series, int pointIndex)
			{
				switch (this._compareMethod)
				{
					case CompareMethod.MoreThan:
						return (point.GetValueByName(this._usingValue) > this._compareValue);

					case CompareMethod.LessThan:
						return (point.GetValueByName(this._usingValue) < this._compareValue);

					case CompareMethod.EqualTo:
						return (point.GetValueByName(this._usingValue) == this._compareValue);

					case CompareMethod.MoreThanOrEqualTo:
						return (point.GetValueByName(this._usingValue) >= this._compareValue);

					case CompareMethod.LessThanOrEqualTo:
						return (point.GetValueByName(this._usingValue) <= this._compareValue);

					case CompareMethod.NotEqualTo:
						return (point.GetValueByName(this._usingValue) != this._compareValue);
				}
				return false;
			}
		}
	}
}

